#include "usermanager.h"
#include "ui_usermanager.h"
#include "changepassworddialog.h"
#include "logmanager.h"
#include <QFileDialog>
#include <QDebug>
#include <QSqlDatabase>
#include <QSqlTableModel>
#include <QModelIndex>
#include <QMessageBox>
#include <QSqlError>
#include <QCryptographicHash>
#include <QInputDialog>
#include <QCloseEvent>
#include <QRegularExpression>
#include <QStyledItemDelegate>

UserManager::UserManager(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::UserManager),
    sqlModel(nullptr),
    changePasswordDialog(nullptr)
{
    ui->setupUi(this);

    // 设置窗口标题
    this->setWindowTitle("用户管理系统");

    // 设置表格属性
    ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
    ui->tableView->setAlternatingRowColors(true);

    setupConnections();

    // 记录系统日志
    LogManager::logSystem("用户管理模块", "用户管理模块初始化完成");
}

UserManager::~UserManager()
{
    // 记录系统日志
    LogManager::logSystem("用户管理模块", "用户管理模块销毁");

    delete ui;
    if (sqlModel) {
        delete sqlModel;
    }
    if (changePasswordDialog) {
        delete changePasswordDialog;
    }
}

void UserManager::setCurrentUserInfo(int userId, const QString &role)
{
    this->currentUserId = userId;
    this->currentUserRole = role;
    applyUserPermissions();  // 应用权限限制

    // 如果是普通用户，自动加载数据
        if (role == "user") {
            loadUserData();
        }

        LogManager::logSystem("用户管理模块",
                            QString("设置用户信息: ID=%1, 角色=%2").arg(userId).arg(role));
}

void UserManager::setupConnections()
{
    // 连接工具栏动作
    connect(ui->actionOpenDB, &QAction::triggered, this, &UserManager::onOpenDatabase);
    connect(ui->actionAdd, &QAction::triggered, this, &UserManager::onAddUser);
    connect(ui->actionInsert, &QAction::triggered, this, &UserManager::onInsertUser);
    connect(ui->actionSave, &QAction::triggered, this, &UserManager::onSaveChanges);
    connect(ui->actionCancel, &QAction::triggered, this, &UserManager::onCancelChanges);
    connect(ui->actionDelete, &QAction::triggered, this, &UserManager::onDeleteUser);
    connect(ui->actionResetPwd, &QAction::triggered, this, &UserManager::onResetPassword);
    connect(ui->actionModifyPwd, &QAction::triggered, this, &UserManager::onChangePassword);

    // 连接搜索按钮
    connect(ui->btnSearch, &QPushButton::clicked, this, &UserManager::onSearchUser);
}

QString UserManager::hashPassword(const QString &password)
{
    QByteArray hash = QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Sha256);
    return QString(hash.toHex());
}

bool UserManager::validatePasswordStrength(const QString &password)
{
    if (password.length() < 8) {
        return false;
    }

    QRegularExpression upperCase("[A-Z]");
    QRegularExpression lowerCase("[a-z]");
    QRegularExpression digit("[0-9]");

    return (password.contains(upperCase) &&
            password.contains(lowerCase) &&
            password.contains(digit));
}

void UserManager::applyUserPermissions()
{
    if (currentUserRole == "user") {
                // 禁用工具栏动作
                ui->actionOpenDB->setEnabled(false);
                ui->actionAdd->setEnabled(false);
                ui->actionInsert->setEnabled(false);
                ui->actionDelete->setEnabled(false);
                ui->actionResetPwd->setEnabled(false);

                // 只能修改密码
                ui->actionModifyPwd->setEnabled(true);
                ui->actionSave->setEnabled(true);
                ui->actionCancel->setEnabled(true);

                // 禁用搜索按钮
                ui->btnSearch->setEnabled(false);
                ui->lineEditSearch->setEnabled(false);

                // 设置表格为只读
                if (sqlModel) {
                    setupUserTableViewPermissions();
                }
    }
}

void UserManager::setupUserTableViewPermissions()
{
    if (!sqlModel) return;

    if (currentUserRole == "user") {
        // 隐藏敏感列
        ui->tableView->hideColumn(sqlModel->fieldIndex("password"));
        ui->tableView->hideColumn(sqlModel->fieldIndex("role"));

        // 允许用户修改 email、phone、nickname
        ui->tableView->setEditTriggers(QAbstractItemView::DoubleClicked |
                                       QAbstractItemView::EditKeyPressed);

        // 创建一个委托，禁止修改特定字段
        for (int i = 0; i < sqlModel->columnCount(); ++i) {
            QString fieldName = sqlModel->headerData(i, Qt::Horizontal).toString();
            if (fieldName == "user_id" ||
                fieldName == "username" ||
                fieldName == "role" ||
                fieldName == "password" ||
                fieldName == "created_at") {
                // 禁止编辑这些列
                ui->tableView->setItemDelegateForColumn(i, new QStyledItemDelegate(this));
            }
        }

        LogManager::logSystem("用户管理模块",
            QString("普通用户权限: 仅可修改邮箱/电话/昵称"));
    } else if (currentUserRole == "admin") {
        // 管理员可以编辑所有字段
        ui->tableView->hideColumn(sqlModel->fieldIndex("password"));
        ui->tableView->setEditTriggers(QAbstractItemView::DoubleClicked |
                                       QAbstractItemView::EditKeyPressed);
    }
}


void UserManager::loadUserData()
{
    // 使用默认数据库连接
        QSqlDatabase db = QSqlDatabase::database();

        if (!db.isValid() || !db.isOpen()) {
            QMessageBox::warning(this, "提示", "数据库未连接，请联系管理员");
            LogManager::logError("自动加载用户数据失败: 数据库未连接");
            return;
        }

        // 创建模型
        if (sqlModel) {
            delete sqlModel;
        }

        sqlModel = new QSqlTableModel(this, db);
        sqlModel->setTable("users");
        sqlModel->setEditStrategy(QSqlTableModel::OnManualSubmit);

        // 只加载当前用户的数据
        if (currentUserRole == "user") {
            sqlModel->setFilter(QString("user_id = %1").arg(currentUserId));
        }

        if (sqlModel->select()) {
            ui->tableView->setModel(sqlModel);
            editHeaderData();
            ui->tableView->setAlternatingRowColors(true);

            // 应用表格权限
            setupUserTableViewPermissions();

            int userCount = sqlModel->rowCount();
            ui->statusbar->showMessage(QString("已加载您的个人信息"));

            LogManager::logSystem("用户管理模块",
                                QString("自动加载用户数据成功，用户ID: %1").arg(currentUserId));
        } else {
            QString error = sqlModel->lastError().text();
            QMessageBox::critical(this, "错误", "加载用户数据失败: " + error);
            LogManager::logError("自动加载用户数据失败: " + error);
        }
}

void UserManager::editHeaderData()
{
    if (!sqlModel) return;

    // 把表头改为中文
    sqlModel->setHeaderData(sqlModel->fieldIndex("user_id"), Qt::Horizontal, "用户ID");
    sqlModel->setHeaderData(sqlModel->fieldIndex("username"), Qt::Horizontal, "用户名");
    sqlModel->setHeaderData(sqlModel->fieldIndex("email"), Qt::Horizontal, "邮箱");
    sqlModel->setHeaderData(sqlModel->fieldIndex("phone"), Qt::Horizontal, "手机号");
    sqlModel->setHeaderData(sqlModel->fieldIndex("nickname"), Qt::Horizontal, "昵称");
    sqlModel->setHeaderData(sqlModel->fieldIndex("role"), Qt::Horizontal, "角色");
    sqlModel->setHeaderData(sqlModel->fieldIndex("created_at"), Qt::Horizontal, "创建时间");
    sqlModel->setHeaderData(sqlModel->fieldIndex("updated_at"), Qt::Horizontal, "更新时间");

    // 隐藏密码列
    ui->tableView->hideColumn(sqlModel->fieldIndex("password"));
}

void UserManager::onOpenDatabase()
{
    QString fileName = QFileDialog::getOpenFileName(this, "打开数据库", "D:/sqlite/", "*.db");
    if (fileName.isEmpty()) {
        LogManager::logSystem("用户管理模块", "用户取消选择数据库文件");
        return;
    }

    LogManager::logOperation(-1, "打开数据库",
                           QString("选择数据库文件: %1").arg(fileName), "", "");

    QSqlDatabase dataBase = QSqlDatabase::addDatabase("QSQLITE");
    dataBase.setDatabaseName(fileName);

    if (dataBase.open()) {
        qDebug() << "数据库链接成功";

        LogManager::logSystem("用户管理模块",
                            QString("数据库连接成功: %1").arg(fileName));

        sqlModel = new QSqlTableModel(this, dataBase);
        sqlModel->setTable("users");
        sqlModel->setEditStrategy(QSqlTableModel::OnManualSubmit);

        if (sqlModel->select()) {
            ui->tableView->setModel(sqlModel);
            editHeaderData();
            ui->tableView->setAlternatingRowColors(true);

            // 应用权限设置
            setupUserTableViewPermissions();


            int userCount = sqlModel->rowCount();
            ui->statusbar->showMessage(QString("查询成功：共 %1 条数据").arg(userCount));

            LogManager::logSystem("用户管理模块",
                                QString("用户数据加载成功，共 %1 个用户").arg(userCount));
        } else {
            QString error = sqlModel->lastError().text();
            QMessageBox::critical(this, "错误", "查询失败: " + error);
            LogManager::logError("用户数据查询失败: " + error);
        }
    } else {
        QString error = dataBase.lastError().text();
        QMessageBox::critical(this, "错误", "数据库链接失败: " + error);
        LogManager::logError(QString("数据库连接失败: %1, 文件: %2").arg(error).arg(fileName));
    }
}

void UserManager::onAddUser()
{
    if (!sqlModel) {
        QMessageBox::warning(this, "警告", "请先打开数据库");
        LogManager::logError("添加用户失败: 数据库未打开");
        return;
    }

    LogManager::logOperation(-1, "添加用户", "管理员开始添加新用户", "", "");

    // 弹出对话框获取密码
    bool ok;
    QString password = QInputDialog::getText(this, "设置密码",
                                             "请输入新用户的密码:",
                                             QLineEdit::Password,
                                             "", &ok);

    if (!ok || password.isEmpty()) {
        LogManager::logOperation(-1, "添加用户", "用户取消添加操作", "", "");
        return;
    }

    // 对密码进行哈希处理
    QString hashedPassword = hashPassword(password);

    // 插入新行
    int row = sqlModel->rowCount();
    if (!sqlModel->insertRow(row)) {
        QMessageBox::critical(this, "错误", "添加新行失败");
        LogManager::logError("添加用户行失败");
        return;
    }

    // 设置密码字段
    QModelIndex passwordIndex = sqlModel->index(row, sqlModel->fieldIndex("password"));
    sqlModel->setData(passwordIndex, hashedPassword);

    // 设置默认角色
    QModelIndex roleIndex = sqlModel->index(row, sqlModel->fieldIndex("role"));
    sqlModel->setData(roleIndex, "user");

    ui->statusbar->showMessage("已添加新用户行，请填写其他信息后保存");
    LogManager::logSystem("用户管理模块", "已添加新用户行，等待填写信息");
}

void UserManager::onInsertUser()
{
    if (!sqlModel) {
        QMessageBox::warning(this, "警告", "请先打开数据库");
        LogManager::logError("插入用户失败: 数据库未打开");
        return;
    }

    QModelIndex index = ui->tableView->currentIndex();
    if (!index.isValid()) {
        QMessageBox::warning(this, "警告", "请先选择要插入的位置");
        LogManager::logOperation(-1, "插入用户", "未选择插入位置", "", "");
        return;
    }

    LogManager::logOperation(-1, "插入用户",
                           QString("在第 %1 行插入新用户").arg(index.row()), "", "");

    // 弹出对话框获取密码
    bool ok;
    QString password = QInputDialog::getText(this, "设置密码",
                                             "请输入新用户的密码:",
                                             QLineEdit::Password,
                                             "", &ok);

    if (!ok || password.isEmpty()) {
        LogManager::logOperation(-1, "插入用户", "用户取消插入操作", "", "");
        return;
    }

    // 对密码进行哈希处理
    QString hashedPassword = hashPassword(password);

    // 插入新行
    if (!sqlModel->insertRow(index.row())) {
        QMessageBox::critical(this, "错误", "插入新行失败");
        LogManager::logError(QString("在第 %1 行插入用户失败").arg(index.row()));
        return;
    }

    // 设置密码字段
    QModelIndex passwordIndex = sqlModel->index(index.row(), sqlModel->fieldIndex("password"));
    sqlModel->setData(passwordIndex, hashedPassword);

    // 设置默认角色
    QModelIndex roleIndex = sqlModel->index(index.row(), sqlModel->fieldIndex("role"));
    sqlModel->setData(roleIndex, "user");

    ui->statusbar->showMessage("已插入新用户行，请填写其他信息后保存");
    LogManager::logSystem("用户管理模块",
                        QString("在第 %1 行插入新用户，等待填写信息").arg(index.row()));
}

void UserManager::onSaveChanges()
{
    if (!sqlModel) {
        QMessageBox::warning(this, "警告", "请先打开数据库");
        LogManager::logError("保存用户更改失败: 数据库未打开");
        return;
    }

    if (currentUserRole == "user") {
            // 检查是否只修改了自己的数据
            for (int i = 0; i < sqlModel->rowCount(); ++i) {
                int userId = sqlModel->data(sqlModel->index(i, sqlModel->fieldIndex("user_id"))).toInt();
                if (userId != currentUserId) {
                    QMessageBox::warning(this, "权限不足", "您只能修改自己的信息！");
                    sqlModel->revertAll();
                    return;
                }
            }
        }

    LogManager::logOperation(-1, "保存用户更改", "开始保存用户数据更改", "", "");

    if (sqlModel->submitAll()) {
        ui->statusbar->showMessage("保存成功");
        LogManager::logOperation(-1, "保存用户更改",
                               QString("用户数据保存成功，共 %1 个用户").arg(sqlModel->rowCount()),
                               "", "");
    } else {
        QString error = sqlModel->lastError().text();
        QMessageBox::critical(this, "错误", "保存失败: " + error);
        LogManager::logError("保存用户数据失败: " + error);
    }
}

void UserManager::onCancelChanges()
{
    if (!sqlModel) {
        QMessageBox::warning(this, "警告", "请先打开数据库");
        LogManager::logError("取消更改失败: 数据库未打开");
        return;
    }

    sqlModel->revertAll();
    ui->statusbar->showMessage("已取消未保存的更改");
    LogManager::logOperation(-1, "取消用户更改", "用户取消了未保存的更改", "", "");
}

void UserManager::onDeleteUser()
{
    if (!sqlModel) {
        QMessageBox::warning(this, "警告", "请先打开数据库");
        LogManager::logError("删除用户失败: 数据库未打开");
        return;
    }

    QModelIndex index = ui->tableView->currentIndex();
    if (!index.isValid()) {
        QMessageBox::warning(this, "警告", "请选择要删除的用户");
        LogManager::logOperation(-1, "删除用户", "未选择要删除的用户", "", "");
        return;
    }

    QString username = sqlModel->data(sqlModel->index(index.row(),
                               sqlModel->fieldIndex("username"))).toString();
    QString userId = sqlModel->data(sqlModel->index(index.row(),
                               sqlModel->fieldIndex("user_id"))).toString();
    QString role = sqlModel->data(sqlModel->index(index.row(),
                               sqlModel->fieldIndex("role"))).toString();

    LogManager::logOperation(-1, "删除用户",
                           QString("尝试删除用户: %1 (ID: %2, 角色: %3)")
                           .arg(username).arg(userId).arg(role),
                           "", "");

    int state = QMessageBox::question(this, "询问",
                                      QString("确定要删除用户 '%1' 吗？").arg(username),
                                      QMessageBox::Yes | QMessageBox::No);

    if (state == QMessageBox::Yes) {
        sqlModel->removeRow(index.row());
        ui->statusbar->showMessage("已标记删除，请保存更改生效");

        LogManager::logOperation(-1, "删除用户",
                               QString("确认删除用户: %1 (ID: %2, 角色: %3)")
                               .arg(username).arg(userId).arg(role),
                               "", "");

        if (role == "admin") {
            LogManager::logSystem("安全警告",
                                QString("管理员账户被删除: %1 (ID: %2)").arg(username).arg(userId));
        }
    } else {
        LogManager::logOperation(-1, "删除用户",
                               QString("取消删除用户: %1").arg(username), "", "");
    }
}

void UserManager::onSearchUser()
{
    if (!sqlModel) {
        QMessageBox::warning(this, "警告", "请先打开数据库");
        LogManager::logError("搜索用户失败: 数据库未打开");
        return;
    }

    QString searchText = ui->lineEditSearch->text().trimmed();

    LogManager::logOperation(-1, "搜索用户",
                           QString("搜索关键词: %1").arg(searchText), "", "");

    if (!searchText.isEmpty()) {
        sqlModel->setFilter("username LIKE '%" + searchText + "%'");
    } else {
        sqlModel->setFilter("");
    }

    if (sqlModel->select()) {
        int resultCount = sqlModel->rowCount();
        ui->statusbar->showMessage(QString("查询成功：共 %1 条数据").arg(resultCount));

        LogManager::logSystem("用户管理模块",
                            QString("用户搜索成功，关键词: %1，找到 %2 个用户")
                            .arg(searchText).arg(resultCount));
    } else {
        QString error = sqlModel->lastError().text();
        ui->statusbar->showMessage("查询失败");
        LogManager::logError("用户搜索失败: " + error);
    }
}

void UserManager::onResetPassword()
{
    if (!sqlModel) {
        QMessageBox::warning(this, "警告", "请先打开数据库");
        LogManager::logError("重置密码失败: 数据库未打开");
        return;
    }

    QModelIndex index = ui->tableView->currentIndex();
    if (!index.isValid()) {
        QMessageBox::warning(this, "警告", "请先选择要重置密码的用户");
        LogManager::logOperation(-1, "重置密码", "未选择要重置密码的用户", "", "");
        return;
    }

    QString username = sqlModel->data(sqlModel->index(index.row(),
                               sqlModel->fieldIndex("username"))).toString();
    QString userId = sqlModel->data(sqlModel->index(index.row(),
                               sqlModel->fieldIndex("user_id"))).toString();

    LogManager::logOperation(-1, "重置密码",
                           QString("尝试重置用户密码: %1 (ID: %2)").arg(username).arg(userId),
                           "", "");

    // 弹出对话框获取新密码
    bool ok;
    QString password = QInputDialog::getText(this, "重置密码",
                                             QString("请输入用户 %1 的新密码:").arg(username),
                                             QLineEdit::Password,
                                             "", &ok);

    if (!ok || password.isEmpty()) {
        LogManager::logOperation(-1, "重置密码",
                               QString("取消重置用户密码: %1").arg(username), "", "");
        return;
    }

    // 对密码进行哈希处理
    QString hashedPassword = hashPassword(password);

    QModelIndex passwordIndex = sqlModel->index(index.row(), sqlModel->fieldIndex("password"));
        sqlModel->setData(passwordIndex, hashedPassword);

        // 更明确的提示信息
        ui->statusbar->showMessage("密码已重置，请务必点击【保存】按钮使更改生效！");

    LogManager::logOperation(-1, "重置密码",
                           QString("确认重置用户密码: %1 (ID: %2)").arg(username).arg(userId),
                           "", "");
    LogManager::logSystem("安全操作",
                        QString("用户密码已重置: %1 (ID: %2)").arg(username).arg(userId));
}

void UserManager::onChangePassword()
{
    if (!sqlModel) {
        QMessageBox::warning(this, "警告", "请先打开数据库");
        LogManager::logError("修改密码失败: 数据库未打开");
        return;
    }

    QModelIndex index = ui->tableView->currentIndex();
    if (!index.isValid()) {
        QMessageBox::warning(this, "警告", "请先选择要修改密码的用户");
        LogManager::logOperation(-1, "修改密码", "未选择要修改密码的用户", "", "");
        return;
    }

    // 获取用户信息
    QSqlRecord userRecord = sqlModel->record(index.row());
    QString username = userRecord.value("username").toString();
    QString userId = userRecord.value("user_id").toString();

    LogManager::logOperation(-1, "修改密码",
                           QString("开始修改用户密码: %1 (ID: %2)").arg(username).arg(userId),
                           "", "");

    // 创建修改密码对话框
    if (changePasswordDialog) {
        delete changePasswordDialog;
    }
    changePasswordDialog = new ChangePasswordDialog(this, userRecord);

    if (changePasswordDialog->exec() == QDialog::Accepted) {
        if (changePasswordDialog->isPasswordChanged()) {
            // 验证原密码
            QString storedPassword = userRecord.value("password").toString();
            QString hashedOldPassword = hashPassword(changePasswordDialog->getOldPassword());

            if (storedPassword != hashedOldPassword) {
                QMessageBox::warning(this, "警告", "原密码输入错误");
                LogManager::logOperation(-1, "修改密码",
                                       QString("密码修改失败: 原密码错误 - %1").arg(username),
                                       "", "");
                return;
            }

            // 更新密码
            QString hashedNewPassword = hashPassword(changePasswordDialog->getNewPassword());
            QModelIndex passwordIndex = sqlModel->index(index.row(),
                                                       sqlModel->fieldIndex("password"));
            sqlModel->setData(passwordIndex, hashedNewPassword);

            ui->statusbar->showMessage("密码修改成功，请保存更改");

            // 记录成功日志
            LogManager::logOperation(-1, "修改密码",
                                   QString("用户密码修改成功: %1 (ID: %2)").arg(username).arg(userId),
                                   "", "");
            LogManager::logSystem("安全操作",
                                QString("用户密码已修改: %1 (ID: %2)").arg(username).arg(userId));
        }
    } else {
        LogManager::logOperation(-1, "修改密码",
                               QString("用户取消密码修改操作: %1").arg(username), "", "");
    }
}

void UserManager::closeEvent(QCloseEvent *event)
{
    if (sqlModel && sqlModel->isDirty()) {
        LogManager::logOperation(-1, "关闭用户管理", "检测到未保存的更改，询问用户", "", "");

        int result = QMessageBox::question(this, "确认退出",
                                          "有未保存的更改，确定要退出吗？",
                                          QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);

        if (result == QMessageBox::Save) {
            if (!sqlModel->submitAll()) {
                QString error = sqlModel->lastError().text();
                QMessageBox::critical(this, "错误", "保存失败: " + error);
                LogManager::logError("关闭前保存失败: " + error);
                event->ignore();
                return;
            }

            LogManager::logOperation(-1, "关闭用户管理", "用户选择保存更改后退出", "", "");
            event->accept();
        } else if (result == QMessageBox::Discard) {
            LogManager::logOperation(-1, "关闭用户管理", "用户选择放弃未保存的更改并退出", "", "");
            event->accept();
        } else {
            LogManager::logOperation(-1, "关闭用户管理", "用户取消退出操作", "", "");
            event->ignore();
        }
    } else {
        LogManager::logOperation(-1, "关闭用户管理", "没有未保存的更改，正常退出", "", "");
        event->accept();
    }

    if (event->isAccepted()) {
        LogManager::logSystem("用户管理模块", "用户管理窗口关闭");
    }
}
